home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / escalant / escala21.lha / escalante2.1 / src / gm / PVGraphElement.C < prev    next >
C/C++ Source or Header  |  1993-07-15  |  22KB  |  1,159 lines

  1. //
  2. //    Copyright (C) 1993  Jeff McWhirter
  3. //
  4. //$PVGraphElement$
  5. #include "PVGraphElement.h"
  6. #include "PVRelation.h"
  7.  
  8.  
  9. #include "Class.h"
  10.  
  11. #include "String.h"
  12. #include "Set.h"
  13.  
  14.  
  15.  
  16. #include "ClassManager.h"
  17.  
  18.  
  19.  
  20.  
  21.  
  22. #ifdef USEGROUP
  23. NewMetaImpl(PVGraphElement,PVGraphElement_BASE,(TP(protos),TP(InRels),TP(OutRels) ,T(eventMask),TP(name),TP(groups),0));
  24. #endif
  25.  
  26.  
  27. #ifndef USEGROUP
  28. NewMetaImpl(PVGraphElement,PVGraphElement_BASE,(TP(protos),TP(InRels),TP(OutRels) ,T(eventMask),TP(name),0));
  29. #endif
  30.  
  31. #define PVGraphElement_BASE GraphObject
  32.  
  33. ObjList * gVProtoList=0;
  34.  
  35.  
  36.  
  37. bool VInDie = FALSE;
  38. static Set DefaultVDieSet;
  39. Set  * CurrentVDieSet =0;
  40.  
  41. void SetCurrentVDieSet(Set * s){
  42.     CurrentVDieSet =s;
  43. }
  44.  
  45. void StartVDie(){VInDie = TRUE;}
  46. void EndVDie(){
  47.     VInDie = FALSE;
  48.     KillVGraphElements();
  49. }
  50.  
  51.  
  52.  
  53.  
  54.  
  55. void InVDie(bool f){VInDie = f;}
  56.  
  57. static Set GlobalVGraphElementSet;
  58. static Set * CurrentVGraphElementSet;
  59.  
  60.  
  61.  
  62. void SetCurrentVGraphElementSet(Set *s){
  63.     CurrentVGraphElementSet =s;
  64. }
  65.  
  66. Set * GetVGraphElementSet(){
  67.     return (CurrentVGraphElementSet?
  68.             CurrentVGraphElementSet:
  69.             &GlobalVGraphElementSet);
  70. }
  71.  
  72.  
  73. bool gVSetIO = TRUE;
  74.  
  75. void WriteOutVSet(OStream & o){
  76.  
  77. Object * obj;
  78. int cnt =0;
  79. Iter next(GetVGraphElementSet());
  80. while (obj = next())
  81.     if(((PVGraphElement*)obj)->OkToWriteOut())
  82.         cnt ++;
  83.  
  84.  
  85. o << cnt SP;
  86. next.Reset(GetVGraphElementSet());
  87. while (obj = next())
  88.     if(((PVGraphElement*)obj)->OkToWriteOut())
  89.         o << obj SP;
  90.  
  91. }
  92.  
  93.  
  94. bool gVReadingIn = FALSE;
  95.  
  96. void ReadInVSet(IStream & o){
  97. gVReadingIn = TRUE;
  98. int cnt;
  99. o >> cnt;
  100. GetVGraphElementSet()->Empty(cnt);
  101. Object * obj;
  102. for(int i=0; i< cnt;i++){
  103.     o >> obj;
  104.     if(obj) 
  105.         GetVGraphElementSet()->Add(obj);
  106. }
  107. gVReadingIn = FALSE;
  108. }
  109.  
  110.  
  111. Set * GetVDieSet(){return  (CurrentVDieSet?CurrentVDieSet:&DefaultVDieSet);}
  112.  
  113.  
  114.  
  115.  
  116.  
  117. PVGraphElement::PVGraphElement(){
  118. GetVGraphElementSet()->Add(this);
  119. SetAdding(FALSE);
  120. IfFalseDontWriteOutOriginal(TRUE);
  121. IfFalseDontWriteOutClone(TRUE);
  122.  
  123. InRels= new ObjList();
  124. OutRels= new ObjList();
  125. eventMask = 0;
  126. name = 0;
  127. affectedByEvents=0;
  128. protos =0;
  129.  
  130.  
  131. #ifdef USEGROUP
  132. groups =0;
  133. #endif    
  134.  
  135.  
  136. }
  137.  
  138. #ifdef USEGROUP
  139. VGroup * PVGraphElement::GetGroupWithId(int i){
  140. if(!groups)return 0;
  141. Iter next(groups);
  142. VGroup*g;
  143. while(g = (VGroup*)next())
  144.     if(g->GetId() == i) return g;
  145. return 0;
  146. }
  147. #endif
  148.  
  149. void PVGraphElement::InitClone(){
  150. INeedPtr(this);
  151. PVGraphElement_BASE::InitClone();
  152. IfFalseDontWriteOutOriginal(TRUE);
  153. GetVGraphElementSet()->Add(this);
  154. SetDead(FALSE);
  155.  
  156. InRels= new ObjList();
  157. OutRels= new ObjList();
  158.  
  159. eventMask = 0;
  160. affectedByEvents=0;
  161.  
  162. #ifdef USEGROUP
  163. if(groups){
  164.     ObjList * oldg = groups;
  165.     groups = new ObjList();
  166.     Iter next(oldg);
  167.     VGroup * g;
  168.     while(g = (VGroup*) next())
  169.         AddGroup((VGroup*)EscalanteClone(g));
  170. }
  171. #endif
  172. }
  173.  
  174. void PVGraphElement::AddGroupRelation(PVRelation * r){
  175.     PropagateEvent(eAEventAddElement,this,(void*)r);
  176. }
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183. void * PVGraphElement::DoEvent2(Events event, PVGraphElement * elt, void * data, ObjList * list)
  184. {
  185. if(DoneEvent(event))     return 0;
  186.  
  187. bool mylist = FALSE;
  188. ObjList l;
  189. if(list == 0) list = GetEventList(event);
  190. if(list == 0){
  191.     mylist= TRUE;
  192.      list = &l;
  193.     SetEventList(event,list);
  194. }
  195.  
  196. if(list){
  197.     if(list->ContainsPtr((Object*)this)) 
  198.         return 0;
  199.     list->Add((Object*)this);
  200. }
  201. SetEvent(event);
  202. DoEvent(event,elt,data);
  203. ClearEvent(event);
  204. if(mylist) ClearEventList(event);
  205. return 0;
  206. }
  207.  
  208.  
  209. void  * PVGraphElement::DoEvent(Events event,PVGraphElement * ,  void * data){
  210. switch(event){
  211.  case eAEventDie: Die();    break;
  212.  case eAEventDieHint:         if(gDoDieHints) Die();     break;
  213.  case eAEventCopyHint:         if(gDoCopyHints) return (void*)Copy();     
  214.  case eAEventCopy:         return (void*)Copy();     
  215.  case eAEventAddElement:    AddElement((PVGraphElement * )data);     break;
  216.  default: break;
  217. }
  218. return 0;
  219. }    
  220.  
  221.  
  222.  
  223.  
  224. void * PVGraphElement::GetAttribute(int aid,DataType & type){
  225. if(aid == ATTRID(PVGraphElement,name)){
  226.     type = eChar;
  227.     return (void*)name;
  228. }
  229.  
  230. return PVGraphElement_BASE::GetAttribute(aid,type); 
  231. }
  232.  
  233.  
  234.  
  235. void PVGraphElement::ChangeAttribute(int aid, void * data, DataType type){
  236. if(aid == ATTRID(PVGraphElement,name)){
  237.     char * n=0;
  238.     if(ChangeData(data,type,n))
  239.         SetName(n);
  240.  
  241. else PVGraphElement_BASE::ChangeAttribute(aid,data,type);
  242. }
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249. void PVGraphElement::SendAttributeChange(int aid, void * data,DataType type){
  250. PVGraphElement_BASE::SendAttributeChange( aid, data, type);
  251. if(SendingAttrChange()) return;
  252. SendingAttrChange(TRUE);
  253.  
  254.  
  255. PVRelation * r;
  256. if(gDoFromHdAttrMap && InRels){
  257. Iter next(InRels);
  258. while( r = (PVRelation*) next()) {
  259.     if(!r->IsDead())
  260.         r->AttrChangeOnHd(aid,  data, type);
  261. }
  262.  
  263. }
  264.  
  265.  
  266.  
  267. if(gDoFromHdAttrMap && OutRels){
  268. Iter next(OutRels);
  269. while( r = (PVRelation*) next()) {
  270.     if(!r->IsDead())
  271.         r->AttrChangeOnTl(aid,  data, type);
  272. }
  273. }
  274.  
  275. SendingAttrChange(FALSE);
  276. }
  277.  
  278.  
  279.  
  280.  
  281.  
  282. void * PVGraphElement::PropagateEvent(Events event,Events notevents,  PVGraphElement * e,void * data, ObjList * list){
  283.  
  284. if(!OkToPropagateEvent(event))
  285.     return 0;
  286.  
  287. //if(DoneEvent(event)) return 0;
  288. bool mylist = FALSE;
  289. ObjList l;
  290. if(list == 0) list = GetEventList(event);
  291. if(list == 0){
  292.     mylist= TRUE;
  293.      list = &l;
  294.     SetEventList(event,list);
  295. }
  296.  
  297. if(e == 0)     e = this;
  298. list->Add((Object*)this);
  299. SetEvent(event);
  300. void * rv = PropagateEvent2(event, notevents,e,data, list);
  301. ClearEvent(event);
  302. if(mylist) ClearEventList(event);
  303. return rv;
  304. }
  305.  
  306.  
  307.  
  308.  
  309.  
  310. void * PVGraphElement::PropagateEvent2(Events event,Events notevents,  PVGraphElement * e,void * data, ObjList * list){
  311.  
  312. PVRelation * r;
  313. if(InRels){
  314. Iter next(InRels);
  315. while(r = (PVRelation *)next())
  316.     r->EventOccurenceOnHd(event,notevents,e,data,list);
  317. }
  318.  
  319.  
  320. if(OutRels){
  321.     Iter next(OutRels);
  322.     while(r = (PVRelation *)next())
  323.         r->EventOccurenceOnTl(event,notevents,e,data,list);
  324. }
  325.  
  326. return 0;
  327. }
  328.  
  329.  
  330.  
  331. PVGraphElement* PVGraphElement::Copy(){
  332. if(Copied() || HaveIBeenCloned(this)) return 0;
  333. bool iamfirst = StartCloning();
  334. Copied(TRUE);
  335. PVGraphElement * clone = (PVGraphElement*)EscalanteClone(this);
  336. if(!clone) return 0;
  337. clone->Copied(FALSE);
  338.  
  339. if(gDoCopyHints)
  340.     PropagateEvent((Events)(eAEventCopy|eAEventCopyHint),this);
  341. else 
  342.     PropagateEvent(eAEventCopy,this);
  343.  
  344. Copied(FALSE);
  345. if(iamfirst) EndCloning();
  346. return clone;
  347. }
  348.  
  349.  
  350.  
  351. void PVGraphElement::SetDead(bool f){
  352.     if(f && !IsDead()) GetVDieSet()->Add((Object*)this);
  353.     else if(!f && IsDead())  GetVDieSet()->Remove((Object*)this);
  354.     PVGraphElement_BASE::SetDead(f);
  355. }
  356.  
  357.  
  358. void PVGraphElement::Die(){
  359. if(IsDead()) return;
  360. PVGraphElement_BASE::Die();
  361.  
  362.  
  363. Send(0,eAEventDie,0);
  364.  
  365. if(gDoDieHints)
  366.     PropagateEvent((Events)(eAEventDie|eAEventDieHint),this);
  367. else
  368.     PropagateEvent(eAEventDie,this);
  369.  
  370.  
  371. MS_Die();
  372.  
  373. }
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381. PVGraphElement::~PVGraphElement(){
  382.  
  383. #ifdef USEGROUP
  384. if(groups) groups->FreeAll();
  385. SafeDelete(groups);
  386. #endif
  387.  
  388. if(!IsDead()) Die(); 
  389. GetVGraphElementSet()->Remove(this);
  390. GetVDieSet()->Remove(this);
  391.  
  392.  
  393. if(InRels){
  394.     InRels-> ForEach(PVRelation,SetHead)(0);
  395. }
  396. if(OutRels){
  397.     OutRels->ForEach(PVRelation,SetTail)(0);
  398. }
  399.  
  400. SafeDelete( InRels);
  401. SafeDelete( OutRels);
  402. }
  403.  
  404.  
  405.  
  406. PVGraphElement * PVGraphElement::GetPrototypeOfClass(class Class * c)
  407. {
  408. if(!protos) return 0;
  409. Iter next(protos);
  410. PVGraphElement * e;
  411. PVGraphElement * close=0;
  412.  
  413. while(e = (PVGraphElement*) next())
  414. {
  415.     if(e->IsA()->IsEqual(c))return e;
  416.     if(e->IsA()->isKindOf(c)) close = e;
  417. }
  418. return close;
  419. }
  420.  
  421.  
  422.  
  423. OStream& PVGraphElement::PrintOn(OStream& s){
  424. PVGraphElement_BASE::PrintOn(s);
  425. if(!gVSetIO){
  426.     s << InRels SP;
  427.     s << OutRels SP;
  428. }
  429.  
  430. s << protos SP;
  431. s << affectedByEvents SP;
  432. #ifdef USEGROUP
  433. s << groups SP;
  434. #endif
  435. s.PrintString(name);
  436. s SP;
  437. return s;
  438. }
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445. IStream& PVGraphElement::ReadFrom(IStream& s){
  446. PVGraphElement_BASE::ReadFrom(s);
  447. GetVGraphElementSet()->Add(this);
  448. if(!gVSetIO){
  449.     s >> InRels ;
  450.     s >> OutRels ;
  451. }
  452. else {
  453.     InRels = new ObjList();
  454.     OutRels = new ObjList();
  455. }
  456. s >> protos;
  457. s >> affectedByEvents ;
  458.  
  459. #ifdef USEGROUP
  460. s >> groups ;
  461. #endif
  462.  
  463. s.ReadString(&name);
  464. eventMask =0;
  465. return s;
  466. }
  467.  
  468.  
  469.  
  470. void PVGraphElement::AddInRelation(PVRelation *r){
  471. if(!r) return;
  472. if(!InRels) InRels = new ObjList();
  473. InRels->Add((Object*)r);
  474.  
  475. #ifdef USEGROUP
  476. if(!gVReadingIn && groups){//These brackets have to be here.
  477.     groups-> ForEach(VGroup,AddedInRelation)(r);    
  478. }
  479. #endif
  480. }
  481.  
  482. void PVGraphElement::RemoveInRelation(PVRelation *r){
  483. if(!InRels) return;
  484. InRels->RemovePtr((Object*)r);
  485.  
  486. #ifdef USEGROUP
  487. if(groups){//These brackets have to be here.
  488.     groups-> ForEach(VGroup,RemovedInRelation)(r);    
  489. }
  490. #endif
  491.  
  492. }
  493.  
  494. void PVGraphElement::AddOutRelation(PVRelation *r)
  495. {
  496. if(!r) return;
  497. if(!OutRels) OutRels = new  ObjList();
  498. OutRels->Add((Object*)r);
  499.  
  500. #ifdef USEGROUP
  501. if(!gVReadingIn && groups){//These brackets have to be here.
  502.     groups-> ForEach(VGroup,AddedOutRelation)(r);    
  503. }
  504. #endif
  505.  
  506. }
  507.  
  508. void PVGraphElement::RemoveOutRelation(PVRelation *r)
  509. {
  510. if(!OutRels) return;
  511. OutRels->RemovePtr((Object*)r);
  512.  
  513. #ifdef USEGROUP
  514. if(groups){//These brackets have to be here.
  515.     groups-> ForEach(VGroup,RemovedOutRelation)(r);    
  516. }
  517. #endif
  518.  
  519. }
  520.  
  521. void PVGraphElement::NewTail(PVRelation * r, PVGraphElement * elt,PVGraphElement* oldtl){
  522.  
  523. #ifdef USEGROUP
  524. if(groups){//These brackets have to be here.
  525.     groups-> ForEach(VGroup,NewTail)(r,elt,oldtl);    
  526. }
  527. #endif
  528.  
  529. }
  530. void PVGraphElement::NewHead(PVRelation * r, PVGraphElement * elt,PVGraphElement* oldhd){
  531.  
  532. #ifdef USEGROUP
  533. if(groups){
  534.     groups-> ForEach(VGroup,NewHead)(r,elt,oldhd);    
  535. }
  536. #endif
  537.  
  538. }
  539.  
  540.  
  541.  
  542.  
  543. void PVGraphElement::GetRelsWithDep(ObjList & l, Events events, DepTypes type,RDir dir){
  544. ObjList * rlist = GetRelations(dir);
  545. if(!rlist) return;
  546. Iter next(rlist);
  547. register PVRelation *r ;
  548. while(r = (PVRelation*)next())
  549.     if(r->GetEventDep(events,type)) l.Add((Object*)r);
  550. }
  551.  
  552.  
  553.  
  554. PVRelation * PVGraphElement::GetRelation(PVGraphElement * e,    RDir dir, Class * c,bool isk){
  555. if(c == 0) c = Meta(PVRelation);
  556.  
  557. ObjList * rlist = GetRelations(dir);
  558. if(!rlist) return 0;
  559.  
  560. Iter next(rlist);
  561. PVRelation *r ;
  562. PVGraphElement * other;
  563. while(r = (PVRelation*)next()) {
  564.     if((other = r->GetOtherElement(this)) &&  other==e){
  565.         if(isk){
  566.             if( r->IsA()->isKindOf(c))
  567.                 return(r);
  568.         }
  569.         else if(r->IsA()->IsEqual(c))
  570.             return r;
  571.     }
  572. }
  573. return 0;
  574. }
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581. bool PVGraphElement::PFunc(  VPropFunc func ,
  582.             void * funcdata , 
  583.             int maxhops , 
  584.             RDir dir, 
  585.             VPathFunc path ,
  586.             void * pathdata,
  587.             ObjList * l,
  588.             int hopssofar
  589.              ){
  590.  
  591. if(Propagating() || hopssofar >= maxhops) return TRUE;
  592. if(l && l->ContainsPtr(this)) return TRUE;
  593. ObjList myl;
  594. if(!l) l = &myl;
  595. hopssofar ++;
  596.  
  597.  
  598.     
  599. Propagating(TRUE);
  600. register PVRelation * r;
  601. register PVGraphElement  * elt;
  602. bool OkToContinue = TRUE;
  603. bool ok = TRUE;
  604. register PVGraphElement * root = (PVGraphElement*)this;
  605. if((dir == eIn || dir == eInOut) && InRels){
  606.     Iter next(InRels);
  607.     while(r = (PVRelation*) next()){
  608.         elt = (PVGraphElement*)r->tl;
  609.         if(!path ||  path(root,r,elt,pathdata,hopssofar))
  610.             ok = func(root,r,elt,funcdata,hopssofar,OkToContinue);
  611.         if(!OkToContinue ) {Propagating(FALSE);return FALSE;}
  612.         if(ok && elt && hopssofar < maxhops)  
  613.             if(!elt->PFunc(func,funcdata,maxhops,dir,path, pathdata,l,hopssofar))
  614.                 {Propagating(FALSE);return FALSE;}
  615.  
  616.     }
  617. }
  618.  
  619.  
  620. if((dir == eOut || dir == eInOut) && OutRels){
  621.     Iter next(OutRels);
  622.     while(r = (PVRelation*) next()){
  623.         elt = (PVGraphElement*)r->hd;
  624.         if(!path ||  path(root,r,elt,pathdata,hopssofar))
  625.             ok = func(root,r,elt,funcdata,hopssofar,OkToContinue);
  626.         if(!OkToContinue ) {Propagating(FALSE);return FALSE;}
  627.         if(ok && elt && hopssofar <= maxhops) 
  628.             if(! elt->PFunc(func,funcdata,maxhops,dir,path, pathdata,l,hopssofar)) 
  629.                 {Propagating(FALSE);return FALSE;}
  630.  
  631.     }
  632. }
  633. Propagating(FALSE);
  634. return TRUE;
  635. }
  636.  
  637.  
  638.  
  639.  
  640. bool ClassPath(PVGraphElement*, PVRelation* rel, PVGraphElement* target, void * data, int  ){
  641. if(!data) return TRUE;
  642. TwoClassStruct *s = (TwoClassStruct*)data;
  643. if(s->c1 && rel)
  644.     if(!rel->IsA()->isKindOf(s->c1))  return FALSE;
  645.  
  646. if(s->c2 && target)
  647.     if(!target->IsA()->isKindOf(s->c2))  return FALSE;
  648.  
  649. return TRUE;
  650.  
  651. }
  652.  
  653. bool PVGraphElement::PFunc(VPropFunc func ,
  654.             void * funcdata , 
  655.             Class* relc ,
  656.             Class*eltc,
  657.             int hops, 
  658.             RDir dir){
  659.  
  660.         TwoClassStruct s;
  661.         s.c1 = relc;
  662.         s.c2 = eltc;
  663.         bool result = PFunc(func,funcdata,hops,dir,ClassPath,(void*)&s);
  664.         return result;
  665. }
  666.     
  667.  
  668.  
  669. void KillVGraphElements(){
  670.     PVGraphElement * o;
  671.     Iter next(GetVDieSet());
  672.     while(o = (PVGraphElement*)next()) {
  673.         GetVDieSet()->Remove(o);
  674.         if(o->IsDead())
  675.             SafeDelete(o);
  676.     }
  677. }
  678.  
  679.  
  680.  
  681. PVRelation * PVGraphElement::GetDefaultRelation(PVGraphElement * tl,PVGraphElement * hd,Class * relclass)
  682. {
  683. PVGraphElement * phd, * ptl;
  684. PVRelation * prel;
  685. PVRelation *isaisk=0,*iskisk = 0;
  686.  
  687. if(relclass == 0) relclass = Meta(PVRelation);
  688.  
  689.  
  690. ObjList dummy;
  691. Iter next(&dummy);
  692.  
  693. ObjList * plist=0;
  694. for(int  cnt = 0; cnt < 2; cnt++){
  695. if(cnt ==  0) plist = protos;
  696. else {
  697.     if(protos !=  gVProtoList)
  698.          plist = gVProtoList;
  699.     else plist =0;
  700. }
  701.  
  702. if(plist){
  703.     next.Reset(plist);
  704.     while(prel = (PVRelation*)next()){
  705.         if( prel->IsA()->isKindOf(relclass)){
  706.             phd = prel->GetHead();
  707.             ptl = prel->GetTail();
  708.             if(phd && ptl){
  709.                 if((hd && phd ->IsA()->IsEqual(hd->IsA())) || ! hd){
  710.                     if((tl && ptl ->IsA()->IsEqual(tl->IsA()) ) || ! tl)
  711.                         return (PVRelation*)EscalanteClone(prel); 
  712.                     if((tl && tl ->IsA()->isKindOf(ptl->IsA()) ) || ! tl)
  713.                         isaisk = prel;
  714.                 }
  715.                 if((hd && hd ->IsA()->isKindOf(phd->IsA())) || ! hd) {
  716.                     if((tl && ptl ->IsA()->IsEqual(tl->IsA()) ) || ! tl)
  717.                         isaisk = prel;
  718.                     else if((tl && tl ->IsA()->isKindOf(ptl->IsA()) ) || ! tl)
  719.                         iskisk = prel;
  720.                 }
  721.             }
  722.         }
  723.     }
  724. }    
  725. }
  726. if(isaisk) return (PVRelation*)EscalanteClone(isaisk); 
  727. else  if(iskisk) return (PVRelation*)EscalanteClone(iskisk); 
  728. else return 0;
  729. }
  730.  
  731. void PVGraphElement::AddElement(PVGraphElement * elt,PVRelation * rel){
  732.     if(elt == 0)     return;
  733.     if(!elt->AddOnCloning())return;
  734.     if(AddOnlyIfHaveProto()) {
  735.         bool haveone = FALSE;
  736.         PVGraphElement * pelt;
  737.         if(protos) {
  738.             Iter next(protos);
  739.             while((pelt=(PVGraphElement*)next()) && ! haveone)
  740.                 if(elt->IsA()->isKindOf(pelt->IsA()))
  741.                     haveone = TRUE;
  742.         }
  743.         if(gVProtoList && !haveone && gVProtoList != protos) {
  744.             Iter next(gVProtoList);
  745.             while((pelt=(PVGraphElement*)next()) && ! haveone)
  746.                 if(elt->IsA()->isKindOf(pelt->IsA()))
  747.                     haveone = TRUE;
  748.         }
  749.         if(!haveone) return;
  750.     }
  751.  
  752.  
  753.     if(!rel){
  754.  
  755.         rel =  GetDefaultRelation(this,elt);
  756.  
  757.         if(AddOnlyIfHaveDflt() && !rel) return;
  758.  
  759.     }
  760.  
  761.     if(!rel)    rel = GetDefaultMemberOf();
  762.  
  763.     if(rel){
  764.  
  765.         rel->SetTailHead(this,elt);
  766.  
  767.         PropagateEvent(eAEventAddElement,this,(void*)elt);
  768.     }
  769.  
  770. }
  771.  
  772. void PVGraphElement::AddElements(Set * list) {
  773.     if(!list) return;
  774.     Iter next(list);
  775.     PVGraphElement *e;
  776.     while(e = (PVGraphElement*)next()) AddElement(e);
  777. }
  778.  
  779.  
  780. void PVGraphElement::MoveRelation(PVRelation * r, RDir dir,bool tofront) {
  781. MovePtr((Object*)r,GetRelations(dir),tofront);
  782. }
  783.  
  784.  
  785.  
  786.  
  787.  
  788. void PVGraphElement::Pred( Class *relClass,  Class * eltClass, PVRelation*& retRel,PVGraphElement*&retElt,bool risk, bool eisk){
  789. if(!InRels) return;
  790. if(!relClass) relClass = Meta(PVRelation);
  791. if(!eltClass) eltClass = Meta(PVGraphElement);
  792. Iter next(InRels);
  793.  
  794. register  PVRelation * rel=0;
  795. register  PVGraphElement * elt=0;
  796. while(rel = (PVRelation*)next())
  797.     if(!rel->IsDead()){
  798.         if((risk && rel->IsA()->isKindOf(relClass)) || rel->IsA()->IsEqual(relClass))
  799.             if(elt = rel->GetTail())
  800.                 if((eisk && elt->IsA()->isKindOf(eltClass)) || elt->IsA()->IsEqual(eltClass)){
  801.                     retElt = elt; retRel = rel; return;
  802.                 }
  803.     }
  804. }
  805.  
  806.  
  807.  
  808. void PVGraphElement::Succ( Class *relClass,  Class * eltClass, PVRelation*&retRel,PVGraphElement*&retElt,bool risk, bool eisk){
  809. if(!OutRels) return;
  810. if(!relClass ) relClass = Meta(PVRelation);
  811. if(!eltClass ) eltClass = Meta(PVGraphElement);
  812. Iter next(OutRels);
  813.  
  814. register  PVRelation * rel;
  815. register  PVGraphElement * elt;
  816. while(rel = (PVRelation*)next())
  817.     if(!rel->IsDead()){
  818.         if((risk && rel->IsA()->isKindOf(relClass)) || rel->IsA()->IsEqual(relClass))
  819.             if(elt = rel->GetHead() )
  820.                 if((eisk &&elt->IsA()->isKindOf(eltClass)) || elt->IsA()->IsEqual(eltClass)){
  821.                     retElt = elt; retRel = rel; return;
  822.     }    
  823.     }
  824. }
  825.  
  826.  
  827.  
  828. PVGraphElement * PVGraphElement::Pred( Class *relClass,  Class * eltClass, bool risk, bool eisk){
  829. PVRelation * rel=0;
  830. PVGraphElement * elt=0;
  831. Pred(relClass,eltClass,rel,elt,risk,eisk);
  832. return elt;
  833. }
  834.  
  835.  
  836.  
  837. PVGraphElement * PVGraphElement::Succ(class Class *relClass, class Class * eltClass, bool risk, bool eisk){
  838. PVRelation * rel=0;
  839. PVGraphElement * elt=0;
  840. Succ(relClass,eltClass,rel,elt,risk,eisk);
  841. return elt;
  842. }
  843.  
  844.  
  845.  
  846.  
  847.  
  848. PVRelation * PVGraphElement::RelPred( Class *relClass,  Class * eltClass, bool risk, bool eisk){
  849. PVRelation * rel=0;
  850. PVGraphElement * elt=0;
  851. Pred(relClass,eltClass,rel,elt,risk,eisk);
  852. return rel;
  853. }
  854.  
  855.  
  856.  
  857. PVRelation * PVGraphElement::RelSucc(class Class *relClass, class Class * eltClass, bool risk, bool eisk){
  858. PVRelation * rel=0;
  859. PVGraphElement * elt=0;
  860. Succ(relClass,eltClass,rel,elt,risk,eisk);
  861. return rel;
  862. }
  863.  
  864.  
  865.  
  866.  
  867.  
  868.  
  869.  
  870.  
  871.  
  872.  
  873. #ifdef USEGROUP
  874.  
  875. NewMetaImpl(VOkToAdd,Object,(0));
  876. NewMetaImpl(VRelXElt,VOkToAdd,(0));
  877. NewMetaImpl(VGroup,Object,(TP(elts),0));
  878. NewMetaImpl(VRelGroup,VGroup,(0));
  879. NewMetaImpl(VEltGroup,VGroup,(0));
  880.  
  881. VGroup::~VGroup(){
  882. PVGraphElement  * prev =0;
  883. PVGraphElement  * next =0;
  884. PVRelation * tr;
  885. if(elts && firstProto){
  886.     next=(PVGraphElement*)elts->First();
  887.     prev = theelt;
  888.     if(prev && next){
  889.         tr=prev->GetRelation(next,eOut,firstProto->IsA(),FALSE); 
  890.             if(tr)    tr->Die();
  891.         }
  892. }
  893. if(elts&& relProto){
  894.     PVRelation * tr;
  895.     Iter iter(elts);
  896.     while(next = (PVGraphElement*)iter()){
  897.         next->RemoveObserver(this);
  898.         if(prev && next){
  899.             tr=prev->GetRelation(next,eOut,relProto->IsA(),FALSE); 
  900.             if(tr)
  901.                 tr->Die();
  902.         }
  903.         prev = next;
  904.     
  905.     }
  906. }
  907. SafeDelete(elts);
  908. }
  909.  
  910.  
  911. OStream& VGroup:: PrintOn(OStream&o){
  912. Object::PrintOn(o);
  913. o << id SP;
  914. o << relProto SP;
  915. o << firstProto SP;
  916. o << elts SP;
  917. o << criteria SP;
  918. return o;
  919. }
  920.  
  921.  
  922.  
  923. IStream& VGroup::ReadFrom(IStream&o){
  924. Object::ReadFrom(o);
  925. o >>  id;
  926. o >>  relProto;
  927. o >>  firstProto;
  928. o >>  elts;
  929. o >>  criteria;
  930. return o;
  931. }
  932.  
  933. IStream& VOkToAdd::ReadFrom(IStream&o){
  934. Object::ReadFrom(o);
  935. o >> Enum(dir) ;
  936. return o;
  937. }
  938.  
  939. OStream& VOkToAdd::PrintOn(OStream&o){
  940. Object::PrintOn(o);
  941. o << dir SP;
  942. return o;
  943. }
  944.  
  945.  
  946.  
  947. IStream& VRelXElt::ReadFrom(IStream&o){
  948. VOkToAdd::ReadFrom(o);
  949.  
  950. if(!gClassManager)gClassManager = new ClassManager();
  951.  
  952. char * rn = 0;
  953. char * en = 0;
  954. o.ReadString(&rn);
  955. o.ReadString(&en);
  956. if(rn) relc = gClassManager->Find(rn);
  957. if(en) eltc = gClassManager->Find(en);
  958. return o;
  959. }
  960.  
  961. OStream& VRelXElt::PrintOn(OStream&o){
  962. VOkToAdd::PrintOn(o);
  963.  
  964.  
  965. char * rn = relc?relc->Name():0;
  966. char * en = eltc?eltc->Name():0;
  967.  
  968. o.PrintString(rn);  o SP;
  969. o.PrintString(en);  o SP;
  970.  
  971. return o;
  972. }
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979. void VGroup::AddElement(PVGraphElement*elt){
  980.  
  981.     if(elts == 0) elts = new ObjList();
  982.     else if(elts->Contains(elt)) return;
  983.  
  984.     elt->AddObserver(this);
  985.     PVGraphElement * last = (PVGraphElement*)elts->Last();
  986.      elts->Add(elt);
  987.     if(last)
  988.         Connect(last,elt);
  989.  
  990.     else if(theelt && firstProto){
  991.         PVRelation * newrel = (PVRelation*) EscalanteClone(firstProto);
  992.         theelt->AddGroupRelation(newrel);
  993.         newrel->SetTailHead(theelt,elt);
  994.     }
  995. }
  996.  
  997. void VGroup::RemoveElement(PVGraphElement * elt){
  998.  
  999. if(!elt || !elts) return;
  1000. if(!elts->Contains(elt)) return;
  1001. elt->RemoveObserver(this);
  1002.  
  1003.  
  1004. PVRelation *prev,*next,*tr,*first=0;
  1005.  
  1006.  
  1007. if( ((Object*)elt) == elts->First()  && theelt && firstProto){
  1008.     first=theelt->GetRelation(elt,eOut,firstProto->IsA(),FALSE); 
  1009. //    if(first) first->SetHead(0);
  1010. }
  1011.  
  1012.  
  1013.  
  1014.  
  1015. if(elts->Size() == 1) {
  1016.     elts->Remove(elt); 
  1017.     if(first) first->Die();
  1018.     return;
  1019. }
  1020.  
  1021. //Find the previous and the next elements
  1022. prev = (PVRelation*) elts->BeforePtr(elt);
  1023. next =  (PVRelation*)elts->AfterPtr(elt);
  1024. elts->Remove(elt);
  1025.  
  1026.  
  1027. if(prev && relProto){    
  1028.     tr=prev->GetRelation(elt,eOut,relProto->IsA(),FALSE); 
  1029.     if(tr) tr->Die();
  1030. }
  1031.  
  1032.  
  1033. if(next && relProto){    
  1034.     tr=elt->GetRelation(next,eOut,relProto->IsA(),FALSE);
  1035.     if(tr) tr->Die();
  1036. }
  1037.  
  1038. if(prev && next)    Connect(prev,next);
  1039.  
  1040. if(first && theelt && (prev = (PVRelation*)elts->First()))
  1041.     first->SetHead(prev);
  1042.  
  1043.     
  1044.  
  1045. }
  1046.  
  1047.  
  1048.  
  1049. void VRelGroup::AddedRelation(PVRelation * r,RDir dir){
  1050. if(!r) return;
  1051. if(criteria){
  1052.     if(dir == eOut){
  1053.         if(!criteria->OutRelationOk(r)) return;
  1054.     }
  1055.     else {
  1056.         if(!criteria->InRelationOk(r)) return;
  1057.     }
  1058. }
  1059. AddElement((PVGraphElement*)r);
  1060. }
  1061.  
  1062.  
  1063.  
  1064.  
  1065. void VEltGroup::RemovedInRelation(PVRelation * r){
  1066.     if(r)RemoveElement((PVGraphElement*)r->GetHead());
  1067. }
  1068. void VEltGroup::RemovedOutRelation(PVRelation * r){
  1069.     if(r)RemoveElement((PVGraphElement*)r->GetHead());
  1070. }
  1071.  
  1072. void VEltGroup::AddedInRelation(PVRelation * r){
  1073.     if(r) NewTail(r, r->GetTail(),0);
  1074. }
  1075.  
  1076. void VEltGroup::AddedOutRelation(PVRelation * r){
  1077.     if(r)NewHead(r,r->GetHead(),0);
  1078. }
  1079.  
  1080.  
  1081.  
  1082.  
  1083. void  VEltGroup::NewElt(RDir dir,PVRelation *r ,PVGraphElement* newelt,PVGraphElement* oldelt ){
  1084.     RemoveElement(oldelt);
  1085.     if(!newelt) return;
  1086.     if(criteria){
  1087.         if(dir == eOut){
  1088.             if(!criteria->HeadOk(newelt,r)) return;
  1089.         }
  1090.         else {
  1091.             if(!criteria->TailOk(newelt,r)) return;
  1092.         }
  1093.     }
  1094.     AddElement((PVGraphElement*)newelt);
  1095. }
  1096.  
  1097.  
  1098.  
  1099.  
  1100.  
  1101.  
  1102. void VGroup::Connect(PVGraphElement * e1,PVGraphElement * e2){
  1103. if(e1 && e2 && relProto){
  1104.     PVRelation * newrel = (PVRelation*) EscalanteClone(relProto);
  1105.     if(theelt) theelt->AddGroupRelation(newrel);
  1106.     newrel->SetTailHead(e1,e2);
  1107. }
  1108. }
  1109.  
  1110.  
  1111. void VGroup::DoObserve(int id, int part, void *d , Object *op){
  1112. if(part == eAEventDie && op && elts && elts->Contains(op))
  1113.     RemoveElement((PVGraphElement*)op);
  1114. else if(part == cPartSenderDied && op && elts && elts->Contains(op))
  1115.     elts->Remove(op);
  1116. else Object::DoObserve(id,part,d,op);
  1117. }
  1118.  
  1119. bool VRelXElt::HeadOk(PVGraphElement * hd,PVRelation * r){
  1120.     if(!hd) return FALSE;
  1121.     if(!OutRelationOk(r)) return FALSE;
  1122.     if(eltc) return hd->IsA()->isKindOf(eltc);
  1123.     return TRUE;
  1124.  
  1125. }
  1126.  
  1127. bool VRelXElt::TailOk(PVGraphElement * tl,PVRelation * r){
  1128.     if(!tl) return FALSE;
  1129.     if(!InRelationOk(r)) return FALSE;
  1130.     if(eltc) return tl->IsA()->isKindOf(eltc);
  1131.     return TRUE;
  1132. }
  1133.  
  1134.  
  1135. bool VRelXElt::InRelationOk(PVRelation * r){
  1136.     if(!r) return FALSE;
  1137.     if(!VOkToAdd::InRelationOk(r) ) return FALSE;
  1138.     if(relc) return r->IsA()->isKindOf(relc);
  1139.     else return TRUE;
  1140. }
  1141.  
  1142. bool VRelXElt::OutRelationOk(PVRelation * r){
  1143.     if(!r) return FALSE;
  1144.     if(!VOkToAdd::OutRelationOk(r) ) return FALSE;
  1145.     if(relc) return r->IsA()->isKindOf(relc);
  1146.     else return TRUE;
  1147. }
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153. #endif USEGROUP
  1154.  
  1155.  
  1156.  
  1157.  
  1158.